home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / libtiff / contrib / win95 / tiff2dib.c < prev   
Encoding:
C/C++ Source or Header  |  1999-09-11  |  10.7 KB  |  373 lines

  1. /*************************************************************************
  2.  *
  3.  * Source file for Windows 95/Win32. 
  4.  *
  5.  * The function LoadTIFFinDIB in this source file let you load 
  6.  * a TIFF file and build a memory DIB with it and return the 
  7.  * HANDLE (HDIB) of the memory bloc containing the DIB.
  8.  *
  9.  *  Example : 
  10.  * 
  11.  *   HDIB   hDIB;
  12.  *   hDIB = LoadTIFFinDIB("sample.tif");
  13.  *
  14.  *
  15.  * To build this source file you must include the TIFF library   
  16.  * in your project.
  17.  *
  18.  * 4/12/95   Philippe Tenenhaus   100423.3705@compuserve.com
  19.  *
  20.  ************************************************************************/
  21.  
  22.  
  23. #include "tiffio.h" 
  24.  
  25. #define HDIB HANDLE
  26. #define IS_WIN30_DIB(lpbi)  ((*(LPDWORD)(lpbi)) == sizeof(BITMAPINFOHEADER))
  27. #define CVT(x)      (((x) * 255L) / ((1L<<16)-1))
  28.  
  29. static HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount);
  30. static LPSTR FindDIBBits(LPSTR lpDIB);
  31. static WORD PaletteSize(LPSTR lpDIB);
  32. static WORD DIBNumColors(LPSTR lpDIB);
  33. static int checkcmap(int n, uint16* r, uint16* g, uint16* b);
  34.  
  35.  
  36.  
  37. /*************************************************************************
  38.  *
  39.  * HDIB LoadTIFFinDIB(LPSTR lpFileName) 
  40.  *
  41.  * Parameter:
  42.  *
  43.  * LPSTR lpDIB      - File name of a tiff imag
  44.  *
  45.  * Return Value:
  46.  *
  47.  * LPSTR            - HANDLE of a DIB
  48.  *
  49.  * Description:
  50.  *
  51.  * This function load a TIFF file and build a memory DIB with it
  52.  * and return the HANDLE (HDIB) of the memory bloc containing
  53.  * the DIB.
  54.  *
  55.  * 4/12/95   Philippe Tenenhaus   100423.3705@compuserve.com
  56.  *
  57.  ************************************************************************/
  58.  
  59. HDIB LoadTIFFinDIB(LPSTR lpFileName)    
  60. {
  61.     TIFF          *tif;
  62.     unsigned long imageLength; 
  63.     unsigned long imageWidth; 
  64.     unsigned int  BitsPerSample;
  65.     unsigned long LineSize;
  66.     unsigned int  SamplePerPixel;
  67.     unsigned long RowsPerStrip;  
  68.     int           PhotometricInterpretation;
  69.     long          nrow;
  70.     unsigned long row;
  71.     char          *buf;          
  72.     LPBITMAPINFOHEADER lpDIB; 
  73.     HDIB          hDIB;
  74.     char          *lpBits;
  75.     HGLOBAL       hStrip;
  76.     int           i,l;
  77.     int           Align; 
  78.     
  79.     tif = TIFFOpen(lpFileName, "r");
  80.     
  81.     if (!tif)
  82.         goto TiffOpenError;
  83.     
  84.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imageWidth);
  85.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &imageLength);  
  86.     TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &BitsPerSample);
  87.     TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);  
  88.     TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &RowsPerStrip);   
  89.     TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &PhotometricInterpretation);
  90.            
  91.     LineSize = TIFFScanlineSize(tif); //Number of byte in ine line
  92.  
  93.     SamplePerPixel = (int) (LineSize/imageWidth);
  94.  
  95.     //Align = Number of byte to add at the end of each line of the DIB
  96.     Align = 4 - (LineSize % 4);
  97.     if (Align == 4)    Align = 0;
  98.  
  99.     
  100.     //Create a new DIB
  101.     hDIB = CreateDIB((DWORD) imageWidth, (DWORD) imageLength, (WORD)
  102. (BitsPerSample*SamplePerPixel));
  103.     lpDIB  = (LPBITMAPINFOHEADER) GlobalLock(hDIB);
  104.     if (!lpDIB)
  105.           goto OutOfDIBMemory;
  106.           
  107.     if (lpDIB)
  108.        lpBits = FindDIBBits((LPSTR) lpDIB);
  109.  
  110.     //In the tiff file the lines are save from up to down 
  111.     //In a DIB the lines must be save from down to up
  112.     if (lpBits)
  113.       {
  114.         lpBits = FindDIBBits((LPSTR) lpDIB);
  115.         lpBits+=((imageWidth*SamplePerPixel)+Align)*(imageLength-1);
  116.         //now lpBits pointe on the bottom line
  117.         
  118.         hStrip = GlobalAlloc(GHND,TIFFStripSize(tif));
  119.         buf = GlobalLock(hStrip);           
  120.         
  121.         if (!buf)
  122.            goto OutOfBufMemory;
  123.         
  124.         //PhotometricInterpretation = 2 image is RGB
  125.         //PhotometricInterpretation = 3 image have a color palette              
  126.         if (PhotometricInterpretation == 3)
  127.         {
  128.           uint16* red;
  129.           uint16* green;
  130.           uint16* blue;
  131.           int16 i;
  132.           LPBITMAPINFO lpbmi;   
  133.           int   Palette16Bits;          
  134.            
  135.           TIFFGetField(tif, TIFFTAG_COLORMAP, &red, &green, &blue); 
  136.  
  137.           //Is the palette 16 or 8 bits ?
  138.           if (checkcmap(1<<BitsPerSample, red, green, blue) == 16) 
  139.              Palette16Bits = TRUE;
  140.           else
  141.              Palette16Bits = FALSE;
  142.              
  143.           lpbmi = (LPBITMAPINFO)lpDIB;                      
  144.                 
  145.           //load the palette in the DIB
  146.           for (i = (1<<BitsPerSample)-1; i >= 0; i--) 
  147.             {             
  148.              if (Palette16Bits)
  149.                 {
  150.                   lpbmi->bmiColors[i].rgbRed =(BYTE) CVT(red[i]);
  151.                   lpbmi->bmiColors[i].rgbGreen = (BYTE) CVT(green[i]);
  152.                   lpbmi->bmiColors[i].rgbBlue = (BYTE) CVT(blue[i]);           
  153.                 }
  154.              else
  155.                 {
  156.                   lpbmi->bmiColors[i].rgbRed = (BYTE) red[i];
  157.                   lpbmi->bmiColors[i].rgbGreen = (BYTE) green[i];
  158.                   lpbmi->bmiColors[i].rgbBlue = (BYTE) blue[i];        
  159.                 }
  160.             }  
  161.                  
  162.         }
  163.         
  164.         //read the tiff lines and save them in the DIB
  165.         //with RGB mode, we have to change the order of the 3 samples RGB
  166. <=> BGR
  167.         for (row = 0; row < imageLength; row += RowsPerStrip) 
  168.           {     
  169.             nrow = (row + RowsPerStrip > imageLength ? imageLength - row :
  170. RowsPerStrip);
  171.             if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  172.                 buf, nrow*LineSize)==-1)
  173.                   {
  174.                      goto TiffReadError;
  175.                   } 
  176.             else
  177.                   {  
  178.                     for (l = 0; l < nrow; l++) 
  179.                       {
  180.                          if (SamplePerPixel  == 3)
  181.                            for (i=0;i< (int) (imageWidth);i++)
  182.                               {
  183.                                lpBits[i*SamplePerPixel+0]=buf[l*LineSize+i*Sample
  184. PerPixel+2]; 
  185.                                lpBits[i*SamplePerPixel+1]=buf[l*LineSize+i*Sample
  186. PerPixel+1];
  187.                                lpBits[i*SamplePerPixel+2]=buf[l*LineSize+i*Sample
  188. PerPixel+0];
  189.                               }
  190.                          else
  191.                            memcpy(lpBits, &buf[(int) (l*LineSize)], (int)
  192. imageWidth*SamplePerPixel); 
  193.                           
  194.                          lpBits-=imageWidth*SamplePerPixel+Align;
  195.  
  196.                       }
  197.                  }
  198.           }
  199.         GlobalUnlock(hStrip);
  200.         GlobalFree(hStrip);
  201.         GlobalUnlock(hDIB); 
  202.         TIFFClose(tif);
  203.       }
  204.       
  205.     return hDIB;
  206.     
  207.     OutOfBufMemory:
  208.        
  209.     TiffReadError:
  210.        GlobalUnlock(hDIB); 
  211.        GlobalFree(hStrip);
  212.     OutOfDIBMemory:
  213.        TIFFClose(tif);
  214.     TiffOpenError:
  215.        return (HANDLE) 0;
  216.        
  217.          
  218. }
  219.  
  220.  
  221. static int checkcmap(int n, uint16* r, uint16* g, uint16* b)
  222. {
  223.     while (n-- > 0)
  224.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  225.         return (16);
  226.     
  227.     return (8);
  228. }
  229.  
  230.  
  231.  
  232. /*************************************************************************
  233.  * All the following functions were created by microsoft, they are
  234.  * parts of the sample project "wincap" given with the SDK Win32.
  235.  *
  236.  * Microsoft says that :
  237.  *
  238.  *  You have a royalty-free right to use, modify, reproduce and
  239.  *  distribute the Sample Files (and/or any modified version) in
  240.  *  any way you find useful, provided that you agree that
  241.  *  Microsoft has no warranty obligations or liability for any
  242.  *  Sample Application Files which are modified.
  243.  *
  244.  ************************************************************************/
  245.  
  246. HDIB CreateDIB(DWORD dwWidth, DWORD dwHeight, WORD wBitCount)
  247. {
  248.    BITMAPINFOHEADER bi;         // bitmap header
  249.    LPBITMAPINFOHEADER lpbi;     // pointer to BITMAPINFOHEADER
  250.    DWORD dwLen;                 // size of memory block
  251.    HDIB hDIB;
  252.    DWORD dwBytesPerLine;        // Number of bytes per scanline
  253.  
  254.  
  255.    // Make sure bits per pixel is valid
  256.    if (wBitCount <= 1)
  257.       wBitCount = 1;
  258.    else if (wBitCount <= 4)
  259.       wBitCount = 4;
  260.    else if (wBitCount <= 8)
  261.       wBitCount = 8;
  262.    else if (wBitCount <= 24)
  263.       wBitCount = 24;
  264.    else
  265.       wBitCount = 4;  // set default value to 4 if parameter is bogus
  266.  
  267.    // initialize BITMAPINFOHEADER
  268.    bi.biSize = sizeof(BITMAPINFOHEADER);
  269.    bi.biWidth = dwWidth;         // fill in width from parameter
  270.    bi.biHeight = dwHeight;       // fill in height from parameter
  271.    bi.biPlanes = 1;              // must be 1
  272.    bi.biBitCount = wBitCount;    // from parameter
  273.    bi.biCompression = BI_RGB;    
  274.    bi.biSizeImage = (dwWidth*dwHeight*wBitCount)/8; //0;           // 0's here
  275. mean "default"
  276.    bi.biXPelsPerMeter = 2834; //0;
  277.    bi.biYPelsPerMeter = 2834; //0;
  278.    bi.biClrUsed = 0;
  279.    bi.biClrImportant = 0;
  280.  
  281.    // calculate size of memory block required to store the DIB.  This
  282.    // block should be big enough to hold the BITMAPINFOHEADER, the color
  283.    // table, and the bits
  284.  
  285.    dwBytesPerLine =   (((wBitCount * dwWidth) + 31) / 32 * 4);
  286.    dwLen = bi.biSize + PaletteSize((LPSTR)&bi) + (dwBytesPerLine * dwHeight);
  287.  
  288.    // alloc memory block to store our bitmap
  289.    hDIB = GlobalAlloc(GHND, dwLen);
  290.  
  291.    // major bummer if we couldn't get memory block
  292.    if (!hDIB)
  293.    {
  294.       return NULL;
  295.    }
  296.  
  297.    // lock memory and get pointer to it
  298.    lpbi = (VOID FAR *)GlobalLock(hDIB);
  299.  
  300.    // use our bitmap info structure to fill in first part of
  301.    // our DIB with the BITMAPINFOHEADER
  302.    *lpbi = bi;
  303.  
  304.    // Since we don't know what the colortable and bits should contain,
  305.    // just leave these blank.  Unlock the DIB and return the HDIB.
  306.  
  307.    GlobalUnlock(hDIB);
  308.  
  309.    /* return handle to the DIB */
  310.    return hDIB;
  311. }
  312.  
  313.  
  314. LPSTR FAR FindDIBBits(LPSTR lpDIB)
  315. {
  316.    return (lpDIB + *(LPDWORD)lpDIB + PaletteSize(lpDIB));
  317. }
  318.  
  319.  
  320. WORD FAR PaletteSize(LPSTR lpDIB)
  321. {
  322.    /* calculate the size required by the palette */
  323.    if (IS_WIN30_DIB (lpDIB))
  324.       return (DIBNumColors(lpDIB) * sizeof(RGBQUAD));
  325.    else
  326.       return (DIBNumColors(lpDIB) * sizeof(RGBTRIPLE));
  327. }
  328.  
  329.  
  330. WORD DIBNumColors(LPSTR lpDIB)
  331. {
  332.    WORD wBitCount;  // DIB bit count
  333.  
  334.    /*  If this is a Windows-style DIB, the number of colors in the
  335.     *  color table can be less than the number of bits per pixel
  336.     *  allows for (i.e. lpbi->biClrUsed can be set to some value).
  337.     *  If this is the case, return the appropriate value.
  338.     */
  339.  
  340.    if (IS_WIN30_DIB(lpDIB))
  341.    {
  342.       DWORD dwClrUsed;
  343.  
  344.       dwClrUsed = ((LPBITMAPINFOHEADER)lpDIB)->biClrUsed;
  345.       if (dwClrUsed)
  346.      return (WORD)dwClrUsed;
  347.    }
  348.  
  349.    /*  Calculate the number of colors in the color table based on
  350.     *  the number of bits per pixel for the DIB.
  351.     */
  352.    if (IS_WIN30_DIB(lpDIB))
  353.       wBitCount = ((LPBITMAPINFOHEADER)lpDIB)->biBitCount;
  354.    else
  355.       wBitCount = ((LPBITMAPCOREHEADER)lpDIB)->bcBitCount;
  356.  
  357.    /* return number of colors based on bits per pixel */
  358.    switch (wBitCount)
  359.       {
  360.    case 1:
  361.       return 2;
  362.  
  363.    case 4:
  364.       return 16;
  365.  
  366.    case 8:
  367.       return 256;
  368.  
  369.    default:
  370.       return 0;
  371.       }
  372. }
  373.